#ifndef COMMON_H
#define COMMON_H

typedef unsigned long long uint64;
typedef unsigned int uint32;

//------------------------------------------------------------

enum Color { WHITE=0, BLACK=1 };

#define OPP(c) ((c)^1)

//------------------------------------------------------------
const int FU=0x1;
const int KY=0x2;
const int KE=0x3;
const int GI=0x4;
const int KI=0x5;
const int KA=0x6;
const int HI=0x7;
const int OU=0x8;
const int TO=0x9;
const int NY=0xa;
const int NK=0xb;
const int NG=0xc;
const int UM=0xe;
const int RY=0xf;

#define K_PROM(k) ((k)|8)
#define K_INIT(k) ((k)&7)

#define K_IS_PR(k) (((k)&8))!=0)

#define K_MASK(k) (1<<(k))

//------------------------------------------------------------
#define PIECE(k,c) ((c)<<4|(k))
#define PC_K(pc) ((pc)&15)
#define PC_C(pc) ((pc)>>4)

const int RY_w=PIECE(RY,WHITE);
const int UM_w=PIECE(UM,WHITE);
const int NG_w=PIECE(NG,WHITE);
const int NK_w=PIECE(NK,WHITE);
const int NY_w=PIECE(NY,WHITE);
const int TO_w=PIECE(TO,WHITE);
const int OU_w=PIECE(OU,WHITE);
const int HI_w=PIECE(HI,WHITE);
const int KA_w=PIECE(KA,WHITE);
const int KI_w=PIECE(KI,WHITE);
const int GI_w=PIECE(GI,WHITE);
const int KE_w=PIECE(KE,WHITE);
const int KY_w=PIECE(KY,WHITE);
const int FU_w=PIECE(FU,WHITE);

const int RY_b=PIECE(RY,BLACK);
const int UM_b=PIECE(UM,BLACK);
const int NG_b=PIECE(NG,BLACK);
const int NK_b=PIECE(NK,BLACK);
const int NY_b=PIECE(NY,BLACK);
const int TO_b=PIECE(TO,BLACK);
const int OU_b=PIECE(OU,BLACK);
const int HI_b=PIECE(HI,BLACK);
const int KA_b=PIECE(KA,BLACK);
const int KI_b=PIECE(KI,BLACK);
const int GI_b=PIECE(GI,BLACK);
const int KE_b=PIECE(KE,BLACK);
const int KY_b=PIECE(KY,BLACK);
const int FU_b=PIECE(FU,BLACK);

const int OB=-1;

//------------------------------------------------------------
#define POS(x,y) (((x)<<4)|(y))
#define X(z) ((z)>>4)
#define Y(z) ((z)&15)

#define POS_IS_OB(z) (X(z)<1 || X(z)>9 || Y(z)<1 || Y(z)>9)

const int N=-0x01;
const int S=+0x01;
const int E=-0x10;
const int W=+0x10;
const int NE=N+E;
const int SE=S+E;
const int NW=N+W;
const int SW=S+W;
const int NNE=N+N+E;
const int NNW=N+N+W;
const int SSE=S+S+E;
const int SSW=S+S+W;

// direction index
const int NW_i=0;
const int N_i=1;
const int NE_i=2;
const int W_i=3;
const int E_i=4;
const int SW_i=5;
const int S_i=6;
const int SE_i=7;
const int NNW_i=8;
const int NNE_i=9;
const int SSW_i=10;
const int SSE_i=11;

// bit for short effect
const int NW_b=1<<0;
const int N_b=1<<1;
const int NE_b=1<<2;
const int W_b=1<<3;
const int E_b=1<<4;
const int SW_b=1<<5;
const int S_b=1<<6;
const int SE_b=1<<7;
const int NNW_b=1<<8;
const int NNE_b=1<<9;
const int SSW_b=1<<10;
const int SSE_b=1<<11;

// bits for long effect
const int NW_2b=0x1001<<0;
const int N_2b=0x1001<<1;
const int NE_2b=0x1001<<2;
const int W_2b=0x1001<<3;
const int E_2b=0x1001<<4;
const int SW_2b=0x1001<<5;
const int S_2b=0x1001<<6;
const int SE_2b=0x1001<<7;

//------------------------------------------------------------
enum Handicap { HIRATE };

//------------------------------------------------------------
extern uint64 r64[32][256];

#define R64(pos,pc) (r64[pc][pos])

//------------------------------------------------------------
extern char Dir[12];
extern char LsDir[4096];

extern char Lsb12[4096];
extern char BitCnt12[4096];

#define CLEAR_LSB(a) ((a)&=(a)-1)

//------------------------------------------------------------

extern void common_init();

//------------------------------------------------------------

template<int V>
class Int2Type
{
  enum { value = V; };
};

inline int p2i(int i) { return i; }
inline int p2i(int *p) { return *p; }

//------------------------------------------------------------

#endif // COMMON_H
